package com.jlu.tutorialspringbootoauth.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: jie lu
 * @Data: 2021/10/6
 * @Version: 1.0
 * @Description: JWT工具类，用于校验、生成、解析token
 **/
public class JWTUtils {
    //JWT自定义密钥
    private static String SECRET = "token!Q@W#E$R";

    /**
     * 生产token
     */
    public static String getToken(Map<String, String> map) {
        JWTCreator.Builder builder = JWT.create();

        //设置header部分
        //设置header,有默认值自动填充
        HashMap<String, Object> headerMap = new HashMap<>();
        headerMap.put("alg", "HS256");
        headerMap.put("typ", "JWT");
        builder.withHeader(headerMap);

        //设置payload部分
        //payload中自定义存放的数据，在取数据时候记得数据类型与存放的对应，否则拿不到。
        map.forEach((k, v) -> {
            builder.withClaim(k, v);
        });
        //获取过期时间 Date类型 example:Wed Oct 13 20:21:41 CST 2021
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, 7); //默认7天过期

        //exp (expiration time): 过期时间
        builder.withExpiresAt(instance.getTime());//指定令牌的过期时间
        //iss (issuer)：签发人
        builder.withIssuer("jack");
        //sub (subject)：主题
        builder.withSubject("jwt tutorial demo");
        //aud (audience)：受众
        builder.withAudience("usr");
        //nbf (Not Before)：生效时间
        Calendar calendarNow = Calendar.getInstance();
        calendarNow.add(Calendar.SECOND, 0); //默认7天过期
        builder.withNotBefore(calendarNow.getTime());
        //iat (Issued At)：签发时间
        builder.withIssuedAt(calendarNow.getTime());
        //jti (JWT ID)：编号
        builder.withJWTId("111");
        String token = builder.sign(Algorithm.HMAC256(SECRET));//签名
        return token;
    }

    /**
     * 验证token
     */
    public static DecodedJWT verify(String token) {
        //如果有任何验证异常，此处都会抛出异常
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
        return decodedJWT;
    }

    /**
     * 获取token中的 payload
     */
    public static DecodedJWT getToken(String token) {
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
        return decodedJWT;
    }
}
